package com.keta.foundation.controller;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.persistence.MappedSuperclass;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.hibernate.validator.constraints.br.TituloEleitoral;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.keta.foundation.dataFilter.DataFilter;
import com.keta.foundation.dataFilter.DataFilter.Operator;
import com.keta.foundation.dataFilter.DynamicSpecifications;
import com.keta.foundation.entity.Module;
import com.keta.foundation.entity.Permission;
import com.keta.foundation.log.Log;
import com.keta.foundation.log.LogUtil;
import com.keta.foundation.service.ModuleService;
import com.keta.foundation.service.PermissionService;
import com.keta.foundation.util.dwz.AjaxObject;
import com.keta.foundation.util.dwz.Page;

/**
 * 系统功能模块控制器
 * 
 * @author robin
 *
 */

@Controller
@RequestMapping("/module")
public class ModuleController {

	private static final Logger logger = LoggerFactory.getLogger(LoginController.class);

	private static final String MODULE_SHOW = "module/tree_list";
	private static final String MODULE_TREE = "module/tree";
	private static final String MODULE_LIST = "module/list";
	private static final String MODULE_VIEW = "module/view";
	private static final String MODULE_CREATE = "module/create";
	private static final String MODULE_EDIT = "module/edit";
	private static final String MODULE_LOOUPPARENT = "module/lookup_parent";

	@Autowired
	private ModuleService moduleService;

	@Autowired
	private PermissionService permissionService;

	@RequiresPermissions("Module:view")
	@RequestMapping(value = "/tree_list", method = RequestMethod.GET)
	public String tree_list() {
		return MODULE_SHOW;
	}

	@RequiresPermissions("Module:view")
	@RequestMapping(value = "/tree", method = RequestMethod.GET)
	public String tree(HttpServletRequest request, Model model) {
		Specification<Module> specifications = DynamicSpecifications.byDataFilter(request, Module.class);
		Page page = new Page();
		page.setNumPerPage(Integer.MAX_VALUE);
		page.setOrderDirection(Direction.ASC.toString());
		page.setOrderField("priority");
		List<Module> moduleList = moduleService.getAll(specifications,page);
		model.addAttribute("moduleList", moduleList);

		return MODULE_TREE;
	}

	@RequiresPermissions("Module:view")
	@RequestMapping(value = "/list/{parentId}")
	public String list(@PathVariable Long parentId, Page page, Model model, ServletRequest request) {
		DataFilter filter = new DataFilter("parent.id", Operator.EQ, parentId);
		Specification<Module> specifications = DynamicSpecifications.byDataFilter(request, Module.class, filter);
		page.setOrderDirection(Direction.ASC.toString());
		page.setOrderField("priority");

		List list = moduleService.getAll(specifications, page);

		model.addAttribute("moduleList", list);
		model.addAttribute("parentId", parentId);
		model.addAttribute("page", page);

		return MODULE_LIST;
	}

	@RequiresPermissions("Module:view")
	@RequestMapping(value = "/view/{id}", method = RequestMethod.GET)
	public String view(@PathVariable Long id, Model model) {

		Module module = moduleService.get(id);

		model.addAttribute("module", module);

		return MODULE_VIEW;
	}

	@RequiresPermissions("Module:create")
	@RequestMapping(value = "/create/{parentId}", method = RequestMethod.GET)
	public String preCreate(@PathVariable Long parentId, Model model) {
		Module module = moduleService.get(parentId);
		model.addAttribute("module", module);
		return MODULE_CREATE;
	}

	@Log(message = "添加了模块:{0}")
	@RequiresPermissions("Module:create")
	@RequestMapping(value = "/create", method = RequestMethod.POST)
	public @ResponseBody String create(@Valid Module module) {

		Module parentModel = moduleService.get(module.getParent().getId());
		if (parentModel == null) {
			return AjaxObject.newError("添加模块失败，父模块不存在！").toString();
		}
		// 防止客户端删除权限造成permissionList索引不连续，出现验证不通过
		List<Permission> permissions = new ArrayList<Permission>();
		for (Permission permission : module.getPermissions()) {
			if (StringUtils.isNotBlank(permission.getSn()) && StringUtils.isNotBlank(permission.getName())) {
				permission.setModule(module);
				permissions.add(permission);
			}
		}
		
		
		//重置指定权限
		module.setPermissions(permissions);
		try {
			moduleService.saveOrUpdate(module);
		} catch (Exception ex) {
			logger.error(ex.toString());
			return AjaxObject.newError("添加模块失败!" + ex.getMessage()).toString();
		}
		LogUtil.putArgs(new Object[] { module.getName() });
		return AjaxObject.newOk("添加模块成功！").toString();
	}

	@RequiresPermissions("Module:edit")
	@RequestMapping(value = "/edit/{moduleId}", method = RequestMethod.GET)
	public String preEdit(@PathVariable Long moduleId, Model model) {
		Module module = moduleService.get(moduleId);
		model.addAttribute("module", module);
		return MODULE_EDIT;
	}

	@Log(message = "修改了模块:{0}")
	@RequiresPermissions("Module:edit")
	@RequestMapping(value = "/edit", method = RequestMethod.POST)
	public @ResponseBody String edit(@Valid Module module) {

		Module oldModule = moduleService.get(module.getId());

		// 排除客户端删除权限造成的不连续对象
		List<Permission> savingPermission = new ArrayList<Permission>();
		List<Permission> delPermission = new ArrayList<Permission>();
		if(module.getPermissions()!=null){
			for (Permission permission : module.getPermissions()) {
				if (StringUtils.isNotBlank(permission.getSn())) {
					permission.setModule(module);// 设置Permission的外键
					savingPermission.add(permission);
				}
			}
		}
		
		
		for(Permission permission : oldModule.getPermissions()){
			boolean isExist = false;
			for(Permission perm : savingPermission){
				if(perm.getId()==permission.getId()){
					isExist = true;
				}
			}
			if(isExist==false){
				delPermission.add(permission);
			}
		}
		
		permissionService.delete(delPermission);
		permissionService.save(savingPermission);
		moduleService.saveOrUpdate(module);
		LogUtil.putArgs(new Object[] { module.getName() });
		return AjaxObject.newOk("模块修改成功！").toString();
	}

	@Log(message = "删除了模块:{0}")
	@RequiresPermissions("Module:delete")
	@RequestMapping(value = "/delete/{moduleId}")
	public @ResponseBody String delete(@PathVariable Long moduleId) {

		moduleService.delete(moduleId);
		LogUtil.putArgs(new Object[] { moduleId });
		return AjaxObject.newOk("模块删除成功！").toString();
	}

	@RequiresPermissions("Module:view")
	@RequestMapping(value = "/lookupParent")
	public String lookupParent(Model model) {

		List moduleList = moduleService.getByParentId(ModuleService.RootModuleId);
		model.addAttribute("moduleList", moduleList);
		return MODULE_LOOUPPARENT;
	}

}
